#ifndef __COMPONENT_FLY_AROUND_BEHAVIOR_H__
#define __COMPONENT_FLY_AROUND_BEHAVIOR_H__

#include "ComponentBehavior.hpp"
#include "INoiseListener.hpp"

#include "Engine/MathUtils.hpp"
#include "Engine/Vector2.hpp"

#include "EasyMachine.hpp"

using namespace PocketSurvival::Engine;

namespace PocketSurvival
{
    struct ComponentCreature;
    struct ComponentPathfinding;
    struct ComponentHerdBehavior;

    class SubsystemTerrain;
    class SubsystemTimeOfDay;
    class SubsystemNoise;

    struct ComponentRunAwayBehavior : public ComponentBehavior, public INoiseListener
    {
    protected:
        enum class MachineState
        {
            Inactive,           // 不活跃的
            RunningAway,
        };

        class StateMachine : public EasyMachine<MachineState>
        {
        private:
            ComponentRunAwayBehavior * m_runAwayBehavior;
        public:
            StateMachine(ComponentRunAwayBehavior *flyAroundBehavior);

            virtual void enter() override;
            virtual void update(float dt) override;
            virtual void leave() override;
        };

    protected:
        float m_importanceLevel = 1.0f;
        float m_timeToForgetAttacker;
        bool m_heardNoise;
        entt::entity m_attacker;
        Vector3 m_lastNoiseSourcePosition;

        StateMachine *m_stateMachine;

    public:
        ComponentCreature *componentCreature;
        ComponentPathfinding *componentPathfinding;
        ComponentHerdBehavior *componentHerdBehavior;

        SubsystemTerrain *subsystemTerrain;
        SubsystemTimeOfDay *subsystemTimeOfDay;
        SubsystemNoise *subsystemNoise;

        ComponentRunAwayBehavior() = default;
        ~ComponentRunAwayBehavior();

        virtual float getImportanceLevel() override;

        void runAwayFrom(entt::entity attacker);
        virtual void hearNoise(ComponentBody *sourceBody, const Vector3 &sourcePosition, float loudness) override;
        Vector3 findSafePlace();
        float scoreSafePlace(const Vector3&currentPosition, const Vector3& safePosition, const Vector3& herdPosition, const Vector3& noiseSourcePosition, int32_t contents);


        virtual void update(float dt) override;
        virtual void load(const nlohmann::json &jsonData) override;
        virtual const std::string &getName() const override;
        static const std::string &GetName();
    };
}

#endif
